Add missing pieces from last commit.
authorrobertl <robertl>
Sun, 28 Jun 2009 19:00:58 +0000 (19:00 +0000)
committerrobertl <robertl>
Sun, 28 Jun 2009 19:00:58 +0000 (19:00 +0000)
enigma.c [new file with mode: 0755]
pocketfms_wp.c [new file with mode: 0755]

diff --git a/enigma.c b/enigma.c
new file mode 100755 (executable)
index 0000000..fd00671
--- /dev/null
+++ b/enigma.c
@@ -0,0 +1,220 @@
+/*
+       Enigma route and waypoint file format.
+        http://www.mglavionics.co.za/Docs/Enigma%20Waypoint%20format.pdf
+        Binary data are stored in little endian (Intel)
+
+       Copyright (C) 2009 Tobias Kretschmar, tobias.kretschmar@gmx.de
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; either version 2 of the License, or
+       (at your option) any later version.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "defs.h"
+
+#define MYNAME "Enigma binary route and waypoint file format"
+
+#define WTYPE_WAYPOINT        0 // Waypoint of unspecified type
+#define WTYPE_AIRPORT         1 // Typical assignment for medium sized airports
+#define WTYPE_MAJORAIRPORT    2 // Typical assignment for large and international airports
+#define WTYPE_SEAPLANEBASE    3
+#define WTYPE_AIRFIELD        4 // Typical assignment for smaller municipal airfields, glider fields etc
+#define WTYPE_PRIVATEAIRFIELD 5
+#define WTYPE_ULTRALIGHTFIELD 6
+#define WTYPE_INTERSECTION    7 // (reporting point, boundary crossing)
+#define WTYPE_HELIPORT        8
+#define WTYPE_TACAN           9
+#define WTYPE_NDBDME          10
+#define WTYPE_NDB             11
+#define WTYPE_VORDME          12
+#define WTYPE_VORTAC          13
+#define WTYPE_FANMARKER       14
+#define WTYPE_VOR             15
+#define WTYPE_REPPT           16
+#define WTYPE_LFR             17
+#define WTYPE_UHFNDB          18
+#define WTYPE_MNDB            19
+#define WTYPE_MNDBDME         20
+#define WTYPE_LOM             21
+#define WTYPE_LMM             22
+#define WTYPE_LOCSDF          23
+#define WTYPE_MLSISMLS        24
+#define WTYPE_OTHERNAV        25 // Navaid not falling into any of the above types
+#define WTYPE_ALTITUDECHANGE  26 // Location at which altitude should be changed
+
+union wpt_data {
+    gbint32     wp_altitude;  // Waypoint type 0-6,8: waypoint altitude in feet
+    gbint32     tg_altitude;  // Waypoint type 26: target altitude in feet
+    gbuint32    frequency;    // Waypoint type 9-25: freq in steps of 1000Hz (118Mhz = 180000)
+    gbint32     dummy;        // waypoint type 7, unused
+};
+
+typedef struct enigma_wpt {
+       gbint32                 latitude;
+       gbint32                 longitude;
+    union wpt_data  data;
+    gbuint8         waypoint_type;
+    gbuint8         shortname_len;
+    char            shortname[6];
+    gbuint8         longname_len;
+    char            longname[27];
+} ENIGMA_WPT;
+
+static gbfile *file_in, *file_out;
+
+static void
+rd_init(const char *fname)
+{
+       file_in = gbfopen_le(fname, "rb", MYNAME);
+}
+
+gbint32 decToEnigmaPosition (double val)
+{
+       int degrees = fabs(val);
+       double frac = fabs(val) - degrees;
+       int enigmadeg = degrees * 180000;
+       int enigmafrac = 180000 * frac;
+       int sign = (val < 0) ? -1 : +1;
+       return sign * (enigmadeg + enigmafrac);
+}
+
+float enigmaPositionToDec (gbint32 val)
+{
+       int deg = abs(val) / 180000;
+       int enigmafrac = abs(val) % 180000;
+       double frac = (double)enigmafrac / 180000;
+       int sign = (val < 0) ? -1 : +1;
+       return sign * (deg + frac);
+}
+
+static void
+data_read(void)
+{
+    struct enigma_wpt ewpt;
+    route_head *route = route_head_alloc();
+    route_add_head (route);
+
+       while (1 == gbfread(&ewpt, sizeof (ewpt), 1, file_in)) {
+               waypoint *wpt = waypt_new();
+               wpt->latitude = enigmaPositionToDec(le_read32(&ewpt.latitude));
+               wpt->longitude = enigmaPositionToDec(le_read32(&ewpt.longitude));
+               wpt->shortname = xstrndup(ewpt.shortname, ewpt.shortname_len);
+               wpt->description = xstrndup(ewpt.longname, ewpt.longname_len);
+                switch (ewpt.waypoint_type)
+                {
+                    case WTYPE_WAYPOINT:        // 0
+                    case WTYPE_AIRPORT:         // 1
+                    case WTYPE_MAJORAIRPORT:    // 2
+                    case WTYPE_SEAPLANEBASE:    // 3
+                    case WTYPE_AIRFIELD:        // 4
+                    case WTYPE_PRIVATEAIRFIELD: // 5
+                    case WTYPE_ULTRALIGHTFIELD: // 6
+                    case WTYPE_HELIPORT:        // 8
+                        // waypoint altitude
+                        wpt->altitude = FEET_TO_METERS(le_read32(&ewpt.data.wp_altitude) - 1000);
+                        break;
+                    case WTYPE_ALTITUDECHANGE:  // 26
+                        // target altitude
+                        wpt->altitude = FEET_TO_METERS(le_read32(&ewpt.data.tg_altitude) - 1000);
+                        break;
+                    case WTYPE_INTERSECTION:    // 7
+                        // unused
+                        break;
+                    default:
+                        // frequency
+                        // wpt->frequency = wpt.le_readu32(ewpt.data.frequency);
+                        ;
+                }
+               route_add_wpt(route, wpt);
+       }
+}
+
+static void
+rd_deinit(void)
+{
+       gbfclose(file_in);
+}
+
+static void
+wr_init(const char *fname)
+{
+       file_out = gbfopen_le(fname, "wb", MYNAME);
+}
+
+static void
+route_head_noop(const route_head *wp)
+{
+}
+
+#ifndef min
+#define min(a,b) ((a) < (b)) ? (a) : (b)
+#endif
+#ifndef max
+#define max(a,b) ((a) > (b)) ? (a) : (b)
+#endif
+
+static void
+enigma_waypt_disp(const waypoint *wpt)
+{
+       struct enigma_wpt ewpt;
+
+       memset (&ewpt, 0, sizeof (ewpt));
+
+       le_write32(&ewpt.latitude, decToEnigmaPosition(wpt->latitude));
+       le_write32(&ewpt.longitude, decToEnigmaPosition(wpt->longitude));
+    ewpt.waypoint_type = WTYPE_WAYPOINT;
+       if (wpt->altitude != unknown_alt)
+               le_write32(&ewpt.data.wp_altitude, METERS_TO_FEET(wpt->altitude) + 1000);
+       if (wpt->shortname != NULL)
+       {
+        ewpt.shortname_len = min (6, strlen (wpt->shortname));
+        strncpy(ewpt.shortname, wpt->shortname, 6);
+       }
+       if (wpt->description != NULL)
+       {
+        ewpt.longname_len = min (27, strlen (wpt->description));
+        strncpy(ewpt.longname, wpt->description, 27);
+       }
+       gbfwrite(&ewpt, sizeof (ewpt), 1, file_out);
+}
+
+static void
+data_write(void)
+{
+       route_disp_all(route_head_noop, route_head_noop, enigma_waypt_disp);
+}
+
+static void
+wr_deinit(void)
+{
+       gbfclose(file_in);
+}
+
+ff_vecs_t enigma_vecs = {
+               ff_type_file,
+       { 
+               ff_cap_read | ff_cap_write,     /* waypoints */
+               ff_cap_none,                    /* tracks */
+               ff_cap_read | ff_cap_write      /* routes */
+       },
+               rd_init,
+               wr_init,
+               rd_deinit,
+               wr_deinit,
+               data_read,
+               data_write,
+               NULL,
+               NULL,
+       CET_CHARSET_ASCII, 0    /* CET-REVIEW */
+};
diff --git a/pocketfms_wp.c b/pocketfms_wp.c
new file mode 100755 (executable)
index 0000000..c51c2e2
--- /dev/null
@@ -0,0 +1,129 @@
+/*\r
+       PocketFMS waypoint text files (wpt).\r
+\r
+       Copyright (C) 2009 Tobias Kretschmar, tobias.kretschmar@gmx.de\r
+\r
+       This program is free software; you can redistribute it and/or modify\r
+       it under the terms of the GNU General Public License as published by\r
+       the Free Software Foundation; either version 2 of the License, or\r
+       (at your option) any later version.\r
+\r
+       This program is distributed in the hope that it will be useful,\r
+       but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+       GNU General Public License for more details.\r
+\r
+       You should have received a copy of the GNU General Public License\r
+       along with this program; if not, write to the Free Software\r
+       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA\r
+ */\r
+\r
+#include "defs.h"\r
+#include "csv_util.h"\r
+\r
+#define MYNAME "PocketFMS waypoint text file format"\r
+\r
+static gbfile *file_in, *file_out;\r
+\r
+static void\r
+rd_init(const char *fname)\r
+{\r
+       file_in = gbfopen_le(fname, "r", MYNAME);\r
+}\r
+\r
+double wppos_to_dec(char *value)\r
+{\r
+       if (strstr(value, "°") == NULL)\r
+               return atof(value);\r
+       else \r
+       {\r
+               int degrees, minutes;\r
+               float seconds;\r
+               int sign = 1;\r
+\r
+               if (toupper(value[0]) == 'N' || toupper(value[0]) == 'E' || value[0] == '+')\r
+               {\r
+                       value = &value[1];\r
+               }\r
+               else if (toupper(value[0]) == 'S' || toupper(value[0]) == 'W' || value[0] == '-')\r
+               {\r
+                       value = &value[1];\r
+                       sign = -1;\r
+               }\r
+\r
+               sscanf(value, "%d°%d'%f\"", &degrees, &minutes, &seconds);\r
+               return sign * (degrees + ((float)minutes / 60) + (seconds / 3600));\r
+       }\r
+}\r
+\r
+static void\r
+data_read(void)\r
+{\r
+       char *buff;\r
+       int linecount = 0;\r
+       while ((buff = gbfgetstr(file_in))) {\r
+               char *s;\r
+               waypoint *wpt;\r
+               rtrim(buff);\r
+               if (strlen(buff) == 0)\r
+                       break;\r
+               linecount++;\r
+               wpt = waypt_new();\r
+               s = buff;\r
+               s = csv_lineparse(s, "\\w", "", linecount);\r
+                       wpt->shortname = xstrdup(s);\r
+               s = csv_lineparse(NULL, "\\w", "", linecount);\r
+                       wpt->latitude = wppos_to_dec(s);\r
+               s = csv_lineparse(NULL, "\\w", "", linecount);\r
+                       wpt->longitude = wppos_to_dec(s);\r
+                       waypt_add(wpt);\r
+       }\r
+}\r
+\r
+static void\r
+rd_deinit(void)\r
+{\r
+       gbfclose(file_in);\r
+}\r
+\r
+static void\r
+wr_init(const char *fname)\r
+{\r
+       file_out = gbfopen_le(fname, "w", MYNAME);\r
+}\r
+\r
+static void\r
+enigma_waypt_disp(const waypoint *wpt)\r
+{\r
+       gbfprintf(file_out, "%s %f %f\n", wpt->shortname, wpt->latitude, wpt->longitude);\r
+}\r
+\r
+static void\r
+data_write(void)\r
+{\r
+       waypt_disp_all(enigma_waypt_disp);\r
+}\r
+\r
+static void\r
+wr_deinit(void)\r
+{\r
+       gbfclose(file_out);\r
+}\r
+\r
+ff_vecs_t pocketfms_wp_vecs = {\r
+               ff_type_file,\r
+       { \r
+               ff_cap_read | ff_cap_write,     /* waypoints */\r
+               ff_cap_none,                    /* tracks */\r
+               ff_cap_none,                    /* routes */\r
+       },\r
+               rd_init,\r
+               wr_init,\r
+               rd_deinit,\r
+               wr_deinit,\r
+               data_read,\r
+               data_write,\r
+               NULL,\r
+               NULL,\r
+       CET_CHARSET_ASCII, 0    /* CET-REVIEW */\r
+};\r